package org.shiro.demo.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
import org.shiro.demo.dao.util.Pagination;
import org.shiro.demo.dao.util.QueryCondition;
import org.shiro.demo.entity.Administrator;
import org.shiro.demo.entity.ManagerOrder;
import org.shiro.demo.entity.ManagerOrderDetail;
import org.shiro.demo.entity.OrderProp;
import org.shiro.demo.entity.Product;
import org.shiro.demo.entity.ResponseResult;
import org.shiro.demo.service.IBaseService;
import org.shiro.demo.util.UUIDCreator;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = "/managerOrder")
public class ManagerOrderController {
	@Resource(name = "baseService")
	private IBaseService baseService;
	
	@RequestMapping(value = "/add")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("manager")
	public ResponseResult add(HttpSession session, String description,String orderDetails) {
		ManagerOrder order = new ManagerOrder();

		// 描述=>备注
		order.setDescription(description);
		// 设置订单主人为当前登陆的用户.

		Administrator customer = (Administrator) SecurityUtils.getSubject().getPrincipal();
		order.setUser(customer);
		// order.setUser((User) session.getAttribute("user"));
		// 下单时间即为此时此刻
		order.setPostTime(new Date());
		// 交易时间/付款时间此时未定
		order.setDealTime(null);
		
		Product product;

		try {
			ObjectMapper ob = new ObjectMapper();
			JavaType javaType = ob.getTypeFactory().constructParametricType(List.class, ManagerOrderDetail.class);
			System.out.print("---");
			System.out.print(orderDetails);

			System.out.print("---");

			@SuppressWarnings("unchecked")
			List<ManagerOrderDetail> orderDetailsList = (List<ManagerOrderDetail>) ob.readValue(orderDetails, javaType);
			for (ManagerOrderDetail orderDetail : orderDetailsList) {
				orderDetail.setOrder(order);
			}

			order.setOrderDetails(new HashSet<ManagerOrderDetail>(orderDetailsList));

			double money = 0;
			// price在OrderDetails里面 每一个商品都需要比较！
			for (ManagerOrderDetail orderDetail : orderDetailsList) {
				product = baseService.getById(Product.class, orderDetail.getProductId());
				// 如果订单中 产品的价格不低于现在的产品价格 产品是激活的 货存数量是够的 ===》 可以下单
				if (orderDetail.getPrice() >= product.getPrice() && product.isStatus() && product.getAmount() - orderDetail.getAmount() >= 0) {

					orderDetail.setPrice(product.getPrice());
					orderDetail.setProduct(product);
					money = money + (orderDetail.getAmount() * orderDetail.getPrice());
				} else {
					return new ResponseResult(-1, "订单信息有误", null);
				}
			}
			// product的或存量要减一 <==> 对应的撤销，要加回去
			for (ManagerOrderDetail orderDetail : orderDetailsList) {
				product = baseService.getById(Product.class, orderDetail.getProductId());
				product.setAmount(product.getAmount() - orderDetail.getAmount());
			}

			// 设置订单的初始状态
			OrderProp orderProp = new OrderProp();
			orderProp.setId(1L);
			orderProp.setStatus(1);
			order.setOrderProp(orderProp);
			// 设置uuid。。o字母开头+8位uuid+个人id...
			order.setUuid("m" + UUIDCreator.getShortUuid() + customer.getId() );
			order.setMoney(money);
			// 设置支付方式
			

			baseService.save(order);

		} catch (Exception e) {
			e.printStackTrace();
			return new ResponseResult(0, "下单失败,订单信息有误.", null);
		}

		return new ResponseResult(1, "下单成功", order);
	}
	
	@RequestMapping(value = "/sendProduct")
	@ResponseBody
	@RequiresAuthentication
	public Object sendProduct(@RequestParam(value="uuid")String uuid){
		
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("uuid", QueryCondition.EQ, uuid));
		ManagerOrder managerOrder = (ManagerOrder) baseService.getSingleResult(ManagerOrder.class, queryConditions);
		
		if(managerOrder==null){
			return new ResponseResult(0, "无此订单", "");
		}
		
		if(managerOrder.getOrderProp().getId()!=1L){
			return new ResponseResult(0, "请确认此订单未发货！", "");
		}
		
		managerOrder.setOrderProp(baseService.getById(OrderProp.class, 7L));
		
		try {
			baseService.save(managerOrder);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResponseResult(0,"系统内部出错","");
		}
		
		
		return new ResponseResult(1,"success","");
	}
	
	
	@RequestMapping(value = "/pay")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("manager")
	public Object pay(@RequestParam(value="uuid")String uuid){
		
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("uuid", QueryCondition.EQ, uuid));
		ManagerOrder managerOrder = (ManagerOrder) baseService.getSingleResult(ManagerOrder.class, queryConditions);
		
		if(managerOrder==null){
			return new ResponseResult(0, "无此订单", "");
		}
		
		if(managerOrder.getOrderProp().getId()!=7L){
			return new ResponseResult(0, "请确认此订单已发货！", "");
		}
		
		managerOrder.setOrderProp(baseService.getById(OrderProp.class, 8L));
		
		try {
			baseService.save(managerOrder);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResponseResult(0,"系统内部出错","");
		}
		
		
		return new ResponseResult(1,"success","");
	}
	
	@RequestMapping(value = "/cancelOrder")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("manager")
	public Object cancelOrder(@RequestParam(value="uuid")String uuid){
		
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("uuid", QueryCondition.EQ, uuid));
		ManagerOrder managerOrder = (ManagerOrder) baseService.getSingleResult(ManagerOrder.class, queryConditions);
		
		if(managerOrder==null){
			return new ResponseResult(0, "无此订单", "");
		}
		
		if(managerOrder.getOrderProp().getId()!=1L){
			return new ResponseResult(0, "请确认此订单未发货！", "");
		}
		
		managerOrder.setOrderProp(baseService.getById(OrderProp.class, 4L));
		
		try {
			baseService.save(managerOrder);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResponseResult(0,"系统内部出错","");
		}
		
		
		return new ResponseResult(1,"success","");
	}
	
	
	@RequestMapping(value = "/findByUuid")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("manager")
	public Object findByUuid(@RequestParam(value = "uuid") String uuid) {
		ResponseResult rr = new ResponseResult();
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		queryConditions.add(new QueryCondition("uuid", QueryCondition.EQ, uuid));
		ManagerOrder order = (ManagerOrder) baseService.getSingleResult(ManagerOrder.class, queryConditions);

		Administrator user = getCurrentUser();
		if (user.getId() != order.getUser().getId()) {
			rr.setCode(0);
			rr.setInfo("该订单不属于你");
			return rr;
		}
		rr.setCode(1);
		rr.setInfo("success");
		rr.setObject(order);
		return rr;
	}
	
	private Administrator getCurrentUser() {
		// 设置订单主人为当前登陆的用户.
		Subject currentUser = SecurityUtils.getSubject();
		Administrator customer = (Administrator) currentUser.getPrincipal();
		return customer;
	}
	
	@RequestMapping(value = "/waitSend")
	public @ResponseBody Object waitSend(@RequestParam(value = "pageSize") Integer pageSize, //
			@RequestParam(value = "cpage") Integer pageNumber) {

		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		OrderProp orderProp = baseService.getById(OrderProp.class, 1L);
		queryConditions.add(new QueryCondition("orderProp", QueryCondition.EQ, orderProp));

		Pagination<ManagerOrder> pagination = null;
		pagination = baseService.getPagination(ManagerOrder.class, queryConditions, null, pageNumber, pageSize);
		return new ResponseResult(1, "success", pagination);
	}
	
	
	@RequestMapping(value = "/waitPay")
	public @ResponseBody Object waitPay(@RequestParam(value = "pageSize") Integer pageSize, //
			@RequestParam(value = "cpage") Integer pageNumber) {

		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		OrderProp orderProp = baseService.getById(OrderProp.class, 7L);
		queryConditions.add(new QueryCondition("orderProp", QueryCondition.EQ, orderProp));

		Pagination<ManagerOrder> pagination = null;
		pagination = baseService.getPagination(ManagerOrder.class, queryConditions, null, pageNumber, pageSize);
		return new ResponseResult(1, "success", pagination);
	}
	
	
	/**	查询接口*/
	@RequestMapping(value = "/findOrdersByUser")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles("manager")
	public Object findByUser(@RequestParam(value = "pageSize") Integer pageSize, //
			@RequestParam(value = "pageNumber") Integer pageNumber,@RequestParam(value = "propId") long propId) {
		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();

		// User user = userService.getById(User.class, userId);
		Administrator user = getCurrentUser();
		queryConditions.add(new QueryCondition("user", "=", user));

		// 若propId是null表示拿所有的订单
		if (propId != 0) {
			OrderProp orderProp = baseService.getById(OrderProp.class, propId);
			queryConditions.add(new QueryCondition("orderProp", QueryCondition.EQ, orderProp));
		}

		Pagination<ManagerOrder> pagination = baseService.getPagination(ManagerOrder.class, queryConditions, "ORDER　BY o.postTime desc", pageNumber, pageSize);
		return new ResponseResult(1, "获取用户 " + user.getPhone() + " 的订单成功", pagination);
	}
	
	
	@RequestMapping(value = "/adminOrders")
	@RequiresAuthentication
	@RequiresRoles("super-administrator")
	@ResponseBody
	public  Object adminGetOrder(@RequestParam(value = "pageSize") Integer pageSize, //
			@RequestParam(value = "pageNumber") Integer pageNumber, @RequestParam(value = "orderBy", required = false) String orderBy, @RequestParam(value = "asc", required = false) Boolean asc, @RequestParam(value = "propId") long propId) {

		List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
		OrderProp orderProp = baseService.getById(OrderProp.class, propId);
		queryConditions.add(new QueryCondition("orderProp", QueryCondition.EQ, orderProp));

		Pagination<ManagerOrder> pagination = null;
		if (orderBy != null && asc != null) {
			pagination = baseService.getPagination(ManagerOrder.class, queryConditions, " order by o." + orderBy + " " + (asc ? " ASC " : " DESC "), pageNumber, pageSize);
		} else {
			pagination = baseService.getPagination(ManagerOrder.class, queryConditions, null, pageNumber, pageSize);
		}
		return new ResponseResult(1,"success",pagination);
	}
	
}
